package com.study.hystrix.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @author: chenhs
 * @date: Created in 9:54 2019/12/14
 **/
@Service
public class CommodityService {

    class Request {
        String commodityCode;
        CompletableFuture<Map<String, Object>> future;
    }


    @Autowired
    private QueryServiceRemoteCall remoteCall;

    /**
     * 将1000次请求放入队列中，然后开启一个定时任务去统一执行。
     */
    BlockingQueue<Request> queue = new LinkedBlockingQueue<>();


    /**
     * 定时任务
     * 每隔10毫秒，从队列里获取任务执行。
     */
    @PostConstruct
    public void init() {
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
        scheduledExecutorService.scheduleAtFixedRate(()->{
            int size = queue.size();
            if (size == 0) {
                return;
            }

            ArrayList<Request> requests = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                requests.add(queue.poll());
            }
            System.out.println("合并了："+ size +"次请求");

            List<String> codes = new ArrayList<>();
            for (Request request : requests) {
                codes.add(request.commodityCode);
            }
            List<Map<String, Object>> responses = remoteCall.queryCommodityBatch(codes);

            //将我们的结果返回给对应的请求！

            //将数据做一个map形态转换
            HashMap<String, Map<String, Object>> responseMap = new HashMap<>();
            for (Map<String, Object> response : responses) {
                String code = (String) response.get("code");
                responseMap.put(code, response);
            }

            //最后的问题-->如何返回给对应的请求？
            for (Request request : requests) {
                Map<String, Object> result = responseMap.get(request.commodityCode);
                request.future.complete(result);
            }

        }, 0, 10, TimeUnit.MILLISECONDS);
    }

    /**
     * 优化 -》1000次请求同时执行
     * 合并1000次请求
     *
     * @param code
     * @return
     */
    public Map<String, Object> queryCommodity(String code) throws ExecutionException, InterruptedException {
        Request request = new Request();
        request.commodityCode = code;

        CompletableFuture<Map<String, Object>> future = new CompletableFuture<>();
        request.future = future;

        queue.add(request);

        //等到定时任务，结果出现了---返回值 ---->阻塞状态！！
        return future.get();
    //    return remoteCall.queryCommodity(code);
    }


    public List<Map<String, Object>> queryCommodityBatch(List<String> codes) {
        return remoteCall.queryCommodityBatch(codes);
    }


}
